home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
005
/
equity.arc
/
MODEHERC.ASM
< prev
next >
Wrap
Assembly Source File
|
1987-02-17
|
4KB
|
135 lines
page 60,132
; Program to let SuperCalc 3, Lotus 123 1A and others
; that may have problems successfully use Hercules
; emulation on the Equity II.
; Since this program remains resident, it is run only
; once, and need not be run until the Equity II is
; powered down or reset.
; It is recommended that this program be the last resident
; program in memory.
; DOS definitions
dos equ 21h ;dos interrupt
term_res equ 31h ;terminate but stay resident
terminate equ 4ch ;terminate process
set_vector equ 25h ;set interrupt vector
get_vector equ 35h ;get interrupt vector
display_str equ 09 ;display string
; Interrupt numbers
video_int equ 10h
; Control characters
cr equ 0dh
lf equ 0ah
code segment para 'CODE'
assume cs:code,ds:nothing,es:nothing,ss:nothing
org 100h
begin: jmp short start
modeherc proc far
new_video_int: ;BIOS video (INT 10H) is redirected here.
;Check to see if user program is requesting
;set mono mode (AH=0, AL=7).
cmp ah,0 ;set video mode?
jnz go_vid ;no, just continue
cmp al,7 ;set mono mode?
jnz go_vid ;if not, goto video int
pushf ;set up for IRET from vid int
push cs ;same
mov word ptr cs:ax_save,ax ;save temporarily
mov ax,offset continue ;get continuation address
push ax ;save it for IRET from video
mov ax,word ptr cs:ax_save ;restore user's AX
go_vid: jmp dword ptr cs:old_video_int_off ;go to real int 10h
continue:
push dx
push ax
mov dx,03bfh ;hercules configuration port
mov al,03 ;graphics and page 1 can be used now
out dx,al ;set it
pop ax
pop dx
iret ;back to user
sig_offset equ $ - new_video_int
res_sig: db 'Modeherc'
sig_len equ $ - res_sig
ax_save: dw ?
return_off: dw ?
return_seg: dw ?
old_video_int_off: dw ?
old_video_int_seg: dw ?
last equ $-1 ;mark end of resident code
modeherc endp
assume ds:code
start proc near ;redirect video int to point to
;new_video_int and save current vector
mov sp,offset stack
call chk_res ;see if we're resident already
;returns interrupt address in ES:BX
mov word ptr old_video_int_off,bx ;store offset
mov word ptr old_video_int_seg,es ;store segment
mov dx,offset new_video_int ;DS:DX is now new int address
mov al,video_int ;video interrupt #
mov ah,set_vector ;set vector func
int dos ;set int 10h to new_video_int
mov ax,7 ;reset mono mode before
int 10h ;leaving so hercules is in full mode
mov dx,offset last ;byte count of code to stay resident
mov cl,4
shr dx,cl ;change to paragraph count
inc dx ;just to be sure
mov ah,term_res
mov al,0 ;return code of 0
int dos ;that's all folks
start endp
chk_res proc near ;check if modeherc routine resident
;if not, returns current video interrupt
;in ES:BX
mov ah,get_vector
mov al,video_int ;video interrupt
int dos ;get video interrupt vector in es:bx
mov di,sig_offset ;offset of signature bytes from int offset
add di,bx ;add in interrupt offset
mov si,offset res_sig ;point to sig bytes
mov cx,sig_len ;length of sig
cld
repz cmpsb ;is it there?
jz its_there
ret ;back to main program
its_there: ;print already resident message
pop ax
pop ax
pop ax ;clean up stack
mov dx,offset there_mes
mov ah,display_str
int dos ;display message
mov ah,terminate ;normal end of process
mov al,0
int dos ;back to calling process
there_mes:
db cr,lf,'Already resident ...',cr,lf,'$'
chk_res endp
stk: db 16 dup('STACK...')
stack label word
code ends
end begin